跳到主要内容

边缘检查

Canny 边缘检测

Canny 是一种非常流行的边缘检测算法,它是由 John F. Canny 在 1986 年提出的。Canny 边缘检测算法是一种多阶段的算法,它包括以下几个步骤:

  1. 高斯模糊:去除图像中的噪声。
  2. 计算图像的梯度:使用 Sobel 算子计算图像的梯度。
  3. 非极大值抑制:将图像中的像素点转换为边缘点。
  4. 双阈值检测:确定真实的和潜在的边缘。
  5. 边缘跟踪:通过连接真实的边缘来细化边缘。
  6. 显示结果:将边缘可视化。
import cv2
import numpy as np
import os

# 读取图像
img_path = os.path.join(os.path.dirname(__file__), "images", "original_image.png")
image = cv2.imread(img_path)

# 转换为灰度图
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# 应用高斯模糊
blurred_image = cv2.GaussianBlur(gray_image, (5, 5), 0)
# 展示高斯模糊后的图像
cv2.imshow("Blurred Image", blurred_image)

# 边缘检测
edges = cv2.Canny(blurred_image, 50, 150)

# 查找轮廓
contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

for contour in contours:
# 计算轮廓的边界框
x, y, w, h = cv2.boundingRect(contour)
# 绘制边界框来可视化聊天框位置
cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2)

# 显示结果
cv2.imshow("Detected Chat Box", image)
cv2.waitKey(0)
cv2.destroyAllWindows()

形态学操作

有时候,我们需要识别的框不是完整的,可能会有一些噪声或者缺失的部分。这时候我们可以使用形态学操作来填充这些缺失的部分。

morphologyEx 函数

这是一个很方便用于处理缺失或者毛边的函数

  • 开运算(open):先腐蚀后膨胀的过程。开运算可以用来消除小黑点,在纤细点处分离物体、平滑较大物体的边界的 同时并不明显改变其面积。
  • 闭运算(close):先膨胀后腐蚀的过程。闭运算可以用来排除小黑洞。
  • 形态学梯度(morph-grad):可以突出团块(blob)的边缘,保留物体的边缘轮廓。
  • 顶帽(top-hat):将突出比原轮廓亮的部分。
  • 黑帽(black-hat):将突出比原轮廓暗的部分。

例如下面使用闭运算来填充缺失的部分

# 识别非背景区域
bg_lower_bound = np.array([max(0, c - 10) for c in background_bgr])
bg_upper_bound = np.array([min(255, c + 10) for c in background_bgr])
bg_mask = cv2.inRange(image, bg_lower_bound, bg_upper_bound)
non_bg_mask = cv2.bitwise_not(bg_mask)

cv2.imshow("non_bg_mask", non_bg_mask)

# 形态学操作:闭运算
kernel = np.ones((5, 5), np.uint8)
closing = cv2.morphologyEx(non_bg_mask, cv2.MORPH_CLOSE, kernel)

cv2.imshow("closing", closing)

使用了闭运算后,可以看到缺失的部分被填充了。

霍夫变换检测直线

OpenCV 的霍夫变换检测直线是一种用于从图像中提取几何形状(如直线)的技术。它基于一个数学变换,可以将图像空间中的形状映射到参数空间中,使得检测直线这类几何形状变得更加简单。霍夫变换对于处理图像中的直线检测非常有用,尤其是在图像中直线可能不完整或者有干扰时。

霍夫变换的基本思想是:在图像空间中的一条直线,在参数空间中可以表示为一个点。反之,图像空间中的一个点,在参数空间中可以表示为一条曲线。通过这种方式,可以将直线检测问题转化为寻找交点的问题。

下面是一个使用霍夫变换检测直线的简单例子,假设你已经有一个聊天软件的截图,并且想要使用霍夫变换找到聊天框中的直线边缘。

首先,你需要安装 OpenCV。如果你还没安装,可以通过 Python 的包管理工具 pip 来安装:

pip install opencv-python

然后,你可以使用以下代码来应用霍夫变换检测直线:

import cv2
import numpy as np

# 读取图片
image = cv2.imread('chat_screenshot.jpg') # 替换为你的截图文件名
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 转换为灰度图

# 应用边缘检测
edges = cv2.Canny(gray, 50, 150, apertureSize=3)

# 使用霍夫变换检测直线
lines = cv2.HoughLines(edges, 1, np.pi/180, 200) # 这里的参数可能需要调整

# 绘制直线
if lines is not None:
for rho, theta in lines[:,0]:
a = np.cos(theta)
b = np.sin(theta)
x0 = a * rho
y0 = b * rho
x1 = int(x0 + 1000 * (-b))
y1 = int(y0 + 1000 * (a))
x2 = int(x0 - 1000 * (-b))
y2 = int(y0 - 1000 * (a))

cv2.line(image, (x1, y1), (x2, y2), (0, 0, 255), 2)

# 显示结果
cv2.imshow('Hough Lines', image)
cv2.waitKey(0)
cv2.destroyAllWindows()

这个例子首先读取了一个图像文件,并将其转换为灰度图像。然后,使用 Canny 算法检测边缘,接着应用霍夫变换来检测直线。检测到的直线会在原图上以红色线条绘制出来。注意,cv2.HoughLines函数的参数(如阈值)可能需要根据你的具体图片进行调整。

这个过程可以帮助你在聊天软件的截图中找到聊天框的直线边缘。然而,具体能否找到,以及找到的直线的准确性,很大程度上取决于截图的质量和内容,以及参数的调整。